package com.dp.mallchat.common.chat.service.adapter;

import com.dp.mallchat.common.chat.domain.entity.Message;
import com.dp.mallchat.common.chat.domain.entity.MessageMark;
import com.dp.mallchat.common.chat.domain.enums.MessageMarkTypeEnum;
import com.dp.mallchat.common.chat.domain.enums.MessageTypeEnum;
import com.dp.mallchat.common.chat.domain.vo.req.SendMessageReq;
import com.dp.mallchat.common.chat.domain.vo.req.msg.MessageExtra;
import com.dp.mallchat.common.chat.domain.vo.req.msg.MsgRecall;
import com.dp.mallchat.common.chat.domain.vo.req.msg.TextMsgReq;
import com.dp.mallchat.common.chat.domain.vo.resp.ChatMessageResp;
import com.dp.mallchat.common.chat.domain.vo.resp.msg.TextMsgResp;
import com.dp.mallchat.common.chat.service.strategy.AbstractMsgHandler;
import com.dp.mallchat.common.chat.service.strategy.MsgHandlerFactory;
import com.dp.mallchat.common.common.domain.enums.DeleteStatusEnum;
import org.springframework.beans.BeanUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author: dupeng
 * @CreateTime: 2024-06-29  20:39
 * @Description: 消息适配器
 */
public class MessageAdapter {


    public static Message buildSaveMessage(Long roomId, Long uid, Integer type) {
        Message message = new Message();
        message.setRoomId(roomId);
        message.setFromUid(uid);
        message.setType(type);
        message.setStatus(DeleteStatusEnum.NORMAL.getStatus());
        return message;
    }


    public static List<ChatMessageResp> buildMsgResp(List<Message> message, List<MessageMark> messageMark, Long uid) {
        Map<Long, List<MessageMark>> msgMarkMap = messageMark.stream().collect(Collectors.groupingBy(MessageMark::getMsgId));
        return message.stream().sorted(Comparator.comparing(Message::getId)).map(msg -> {
            ChatMessageResp chatMessageResp = new ChatMessageResp();
            chatMessageResp.setFromUser(buildFromUser(msg));
            chatMessageResp.setMessage(buildMessage(msg, msgMarkMap.getOrDefault(msg.getId(), new ArrayList<>()), uid));
            return chatMessageResp;
        }).collect(Collectors.toList());
    }

    private static ChatMessageResp.Message buildMessage(Message msg, List<MessageMark> messageMarks, Long uid) {
        ChatMessageResp.Message message = new ChatMessageResp.Message();
        message.setId(msg.getId());
        message.setRoomId(msg.getRoomId());
        message.setType(msg.getType());
        message.setSendTime(msg.getCreateTime());
        AbstractMsgHandler<?> msgHandler = MsgHandlerFactory.getStrategyNoNull(msg.getType());
        if (Objects.nonNull(msgHandler)) {
            message.setBody(msgHandler.showMsg(msg));
        }
        message.setMessageMark(buildMessageMark(messageMarks, uid));
        return message;
    }


    private static ChatMessageResp.MessageMark buildMessageMark(List<MessageMark> messageMarks, Long uid) {
        ChatMessageResp.MessageMark messageMark = new ChatMessageResp.MessageMark();
        Map<Integer, Long> typeMap = messageMarks.stream().map(MessageMark::getType).collect(Collectors.groupingBy(item -> item, Collectors.counting()));
        Optional<MessageMark> messageMarkOptional = messageMarks.stream().filter(item -> item.getUid().equals(uid)).findFirst();

        messageMark.setLikeCount(typeMap.getOrDefault(MessageMarkTypeEnum.LIKE.getType(), 0L).intValue());
        messageMark.setUserLike(Objects.equals(messageMarkOptional.orElse(new MessageMark()).getType(), MessageMarkTypeEnum.LIKE.getType()) ? 1 : 0);
        messageMark.setDislikeCount(typeMap.getOrDefault(MessageMarkTypeEnum.DISLIKE.getType(), 0L).intValue());
        messageMark.setUserDislike(Objects.equals(messageMarkOptional.orElse(new MessageMark()).getType(), MessageMarkTypeEnum.DISLIKE.getType()) ? 1 : 0);
        return messageMark;
    }

    private static ChatMessageResp.UserInfo buildFromUser(Message message) {
        ChatMessageResp.UserInfo userInfo = new ChatMessageResp.UserInfo();
        userInfo.setUid(message.getFromUid());
        return userInfo;
    }


    public static Message buildRecallMsg(Message message, Long uid) {
        MessageExtra extra = message.getExtra();
        MsgRecall recall = new MsgRecall();
        recall.setRecallUid(uid);
        recall.setRecallTime(new Date());
        extra.setRecall(recall);

        Message update = new Message();
        update.setId(message.getId());
        update.setType(MessageTypeEnum.RECALL.getType());
        update.setExtra(extra);
        return update;
    }

    public static SendMessageReq buildAgreeMsg(Long roomId) {
        SendMessageReq chatMessageReq = new SendMessageReq();
        chatMessageReq.setRoomId(roomId);
        chatMessageReq.setMsgType(MessageTypeEnum.TEXT.getType());
        TextMsgReq textMsgReq = new TextMsgReq();
        textMsgReq.setContent("我们已经成为好友了，开始聊天吧");
        chatMessageReq.setBody(textMsgReq);
        return chatMessageReq;
    }
}
